FocusManager enables you to set and change the keyboard and logical focus between attached nodes. More...
#include <kanzi/core.ui/input/focus_manager.hpp>
Classes | |
class | PostFocusMessageArguments |
} More... | |
class | PreFocusMessageArguments |
Message arguments for the pre-focus messages. More... | |
Public Types | |
enum | FocusReason { UnknownReason, FocusChainNavigationReason, DisabledFocusReason, EnabledFocusReason, OtherFocusReason } |
Specifies the reason the node is focused. More... | |
enum | FocusChainDirection { PreviousFocusable, NextFocusable, UpFocusable, DownFocusable, LeftFocusable, RightFocusable } |
Specifies the direction of the focus move. More... | |
Properties | |
{ The property overrides the default focus chain navigation order for the NextFocusable direction. The value must be a relative path to the destination node. To reset the override, set the value of the property to an empty string. | |
static PropertyType< string > | NextFocusNodePathProperty |
static PropertyType< string > | PreviousFocusNodePathProperty |
The property overrides the default focus chain navigation order for the PreviousFocusable direction. More... | |
static PropertyType< string > | UpNavigationNodePathProperty |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the UpFocusable direction in the tryMoveActiveFocus. More... | |
static PropertyType< string > | DownNavigationNodePathProperty |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the DownFocusable direction in the tryMoveActiveFocus. More... | |
static PropertyType< string > | LeftNavigationNodePathProperty |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the LeftFocusable direction in the tryMoveActiveFocus. More... | |
static PropertyType< string > | RightNavigationNodePathProperty |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the RightFocusable direction in the tryMoveActiveFocus. More... | |
static PropertyType< bool > | FocusScopeProperty |
Specifies that the node to which the property is attached is a focus scope. More... | |
static MessageType< PreFocusMessageArguments > | AboutToLoseFocusMessage |
The message dispatched to the active focus node and its ascendants before losing focus. More... | |
static MessageType< PreFocusMessageArguments > | AboutToGainFocusMessage |
The message dispatched to the next focusable node. More... | |
static MessageType< PostFocusMessageArguments > | FocusLostMessage |
Informs the old active focus node about losing the active focus. More... | |
static MessageType< PostFocusMessageArguments > | FocusGainedMessage |
Informs the new active focus node about getting the active focus. More... | |
class | Node |
class | Domain |
class | InputManager |
static string | getNextFocusNodePath (const Node &node) |
Returns the value of the NextFocusNodePathProperty property for the node on which you call this function. More... | |
static void | setNextFocusNodePath (Node &node, string_view next) |
Sets the value of the NextFocusNodePathProperty property. More... | |
static string | getPreviousFocusNodePath (const Node &node) |
Returns the value of the PreviousFocusNodePathProperty property for the node on which you call this function. More... | |
static void | setPreviousFocusNodePath (Node &node, string_view previous) |
Sets the value of the PreviousFocusNodePathProperty property. More... | |
static string | getUpNavigationNodePath (const Node &node) |
Returns the value of the UpNavigationNodePathProperty on the node on which you call this function. More... | |
static void | setUpNavigationNodePath (Node &node, string_view path) |
Sets the value of the UpNavigationNodePathProperty property. More... | |
static string | getDownNavigationNodePath (const Node &node) |
Returns the value of the DownNavigationNodePathProperty on the node on which you call this function. More... | |
static void | setDownNavigationNodePath (Node &node, string_view path) |
Sets the value of the DownNavigationNodePathProperty property. More... | |
static string | getLeftNavigationNodePath (const Node &node) |
Returns the value of the LeftNavigationNodePathProperty on the node on which you call this function. More... | |
static void | setLeftNavigationNodePath (Node &node, string_view path) |
Sets the value of the LeftNavigationNodePathProperty property. More... | |
static string | getRightNavigationNodePath (const Node &node) |
Returns the value of the RightNavigationNodePathProperty on the node on which you call this function. More... | |
static void | setRightNavigationNodePath (Node &node, string_view path) |
Sets the value of the RightNavigationNodePathProperty property. More... | |
static bool | isFocusScope (const Node &node) |
Returns the value of the FocusScopeProperty property for the node on which you call this function. More... | |
static void | setFocusScope (Node &node, bool isScope) |
Sets the value of the FocusScopeProperty property for the node. More... | |
static bool | isFocusFence (const Node &node) |
Returns true if the node is a focus fence. More... | |
static PropertyTypeEditorInfoSharedPtr | makeEditorInfo () |
Creates the property editor info for the FocusManager. More... | |
NodeSharedPtr | trySetActiveFocus (NodeSharedPtr newFocusNode, FocusReason reason) |
Tries to set the active focus to the newFocusNode and specifies the reason for moving the focus. More... | |
NodeSharedPtr | trySetActiveFocus (NodeSharedPtr newFocusNode) |
An overload of trySetActiveFocus() using UnknownReason to move the active focus. More... | |
NodeSharedPtr | tryMoveActiveFocus (FocusChainDirection direction) |
Tries to set the active focus to a node relative to the current active focus node using the focus chain navigation. More... | |
NodeSharedPtr | tryMoveActiveFocusForward () |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in forward direction. More... | |
NodeSharedPtr | tryMoveActiveFocusBackward () |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in backward direction. More... | |
NodeSharedPtr | tryMoveActiveFocusUpward () |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in upward direction. More... | |
NodeSharedPtr | tryMoveActiveFocusDownward () |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in downward direction. More... | |
NodeSharedPtr | tryMoveActiveFocusLeft () |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in left direction. More... | |
NodeSharedPtr | tryMoveActiveFocusRight () |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in right direction. More... | |
NodeSharedPtr | getActiveFocus () const |
Returns the node that has active focus. More... | |
FocusManager enables you to set and change the keyboard and logical focus between attached nodes.
Each domain can have only one instance of the focus manager.
To set focus on a node:
To indicate which node has active focus, Kanzi uses the Node::FocusedProperty. For example, you can use this property as a controller property in a state manager to change the look and behavior of the node that has active focus.
To set active focus to a node:
When you call the trySetActiveFocus() method, the focus manager sends pre-focus and post-focus move messages. The pre-focus move messages, or pre-focus messages, are preconditions for the focus moves. Rejecting any of these messages by the message handlers stops moving the active focus. Post-focus move messages, or post-focus messages, are informative messages. You can use these messages to execute post-focus move actions. The pre-focus messages are AboutToLoseFocusMessage and AboutToGainFocusMessage, and the post-focus messages are FocusLostMessage and FocusGainedMessage.
Kanzi dispatches these messages in this order:
This example shows how you can restrict a Button node to get active focus only on focus chain navigation reason events and lose focus only when other focus reason is received. The pre-focus message handlers are:
To move focus:
When you set the EnabledProperty to false, the Focus Manager removes the active focus status of that node, but does not change the focused state of the node. This means that the logical focus remains on that node until you set the EnabledProperty to true, or move the active focus to another node.
When you disable a node that has active focus, the FocusManager dispatches the FocusLostMessage with DisabledFocusReason. When you re-enable the node, and the focus is not moved to another node, the FocusManager dispatches the FocusGainedMessage with EnabledFocusReason.
Changing VisibleProperty value on a node affects the active focus status of the node the same way as EnabledProperty.
The focus chain is the sequence of nodes which defines the order in which Kanzi applies focus to nodes when the user uses the focus chain navigation keys to move the focus. You as application developer do not need to care about the default navigation, unless you want to override the default behavior, or you want to provide other triggers to move the active focus across the nodes. You can override the default key navigation by handling the Keyboard::KeyDownMessage. Other means of focus chain navigation you can use can be actions that are triggered by property changes, state changes on nodes, and so on. The default chain navigation keys are the Tab and backtab keys. The forward direction chain order uses the pre-order traversal of the node hierarchy, while the backwards direction chain order uses the reverse pre-order traversal.
Kanzi automatically includes in the focus chain all nodes that have the FocusableProperty property set to true. To move the active focus to the next node in the focus chain, call one of the tryMoveActiveFocus() methods.
When Tab and backtab keys are functional keys of a node, such as in a text editor node, that node consumes the keys used by the focus chain navigation. When such node receives focus, to capture the Tab and backtab keys and handle them as normal keys, mark the Keyboard::KeyDownMessage as handled. When you do so, the FocusManager does not react to these keys and keeps the focus on the current active focus node.
To use keys to move focus from such node, you must handle this in the key down message handler for that node, and call one of the tryMoveActiveFocus() methods to move the active focus to the next or previous focusable node.
To move active focus in focus chain from a node which consumes the Tab and backtab keys:
You can manually set the order of nodes in the focus chain by setting the NextFocusNodePathProperty and PreviousFocusNodePathProperty properties of nodes in the focus chain. Use these properties to set the relative path to the next and previous nodes for a node in the focus chain.
In addition to the focus chain navigation, Kanzi provides directional focus navigation to move the focus between nodes based on their rendered position. FocusManager maps up, down, left, and right arrow keys to the corresponding FocusChainDirection. You can override the default behavior the same way as the Tab and backtab key navigation in the example above.
You can set the destination nodes for directional navigation by setting the UpNavigationNodePathProperty, DownNavigationNodePathProperty, LeftNavigationNodePathProperty, and RightNavigationNodePathProperty properties, but these do not affect the default focus chain navigation by any means.
When the path to the destination node specified in the NextFocusNodePathProperty and PreviousFocusNodePathProperty properties is invalid or is disabled, FocusManager falls back to the default focus chain navigation. When the destination node does not meet the focusability requirements, FocusManager continues to look for a focusable node from the destination node onward, taking into account the property values set on the destination nodes affecting the focus chain navigation.
Focus scopes, or scopes, are nodes which assist in focus chain navigation handling. They act like a focus proxy, forwarding the active focus to one of their child nodes which has the logical focus set. A node is a scope when it has the FocusScopeProperty property attached and set to true. Whereas any node can be a scope, there is no reason to make a node a scope if it has no child nodes, and it does not have child nodes attached during runtime.
A node is considered to have logical focus if its LogicalFocusProperty is set to true. When you focus a scope using the trySetActiveFocus() method, the FocusManager looks for a child node that has logical focus set, and moves the active focus to that node. If a scope has several child nodes with logical focus set, only the last of those child nodes stays with logical focus state set, for all the previous child nodes that had logical focus, Kanzi resets the state to false.
To set the active focus on the last logical focus child node of a scope:
When you move the active focus out from the scope, the scope preserves the logical focus state of its last active focus child node. This way when you return the focus on the scope using the trySetActiveFocus() method, Kanzi restores the active focus on this node, unless you change the logical focus on the preserved node by other means.
To move the active focus back on the preserved node of a scope:
When you focus a scope using the focus chain navigation methods, such as tryMoveActiveFocus() and its overrides, depending on the direction given, the scope forwards the active focus to the first or last focusable child node. This happens regardless of whether the scope had a node with the preserved logical focus.
Scopes can have nested scopes. These nested or inner scopes behave in the same way as any other scope: they forward and preserve the logical focus of their child node the same way, regardless of their nested state.
When a node gets active focus, all its ascendant scopes get their logical focus state set. The scopes keep the logical state as long as the active focus node remains in their scope. When the active focus node is moved out from a scope, the topmost ancestor scope that is not holding the new active focus node loses the logical focus state, and all its descendant scopes preserve the logical focus.
This example shows this scenario:
Scopes are "skipped" in the focus chain navigation, because they do not get active focus as long as they have children that can get active focus. If the scopes are disabled, their content cannot get active focus. However, if a scope is marked as not focusable, meaning its FocusableProperty is set to false, the content of the scope can still get active focus under these conditions:
You can override the default focus chain navigation in the same way as for regular focus nodes. When done, focus chain navigation follows the linked nodes and focuses the nodes or scopes linked.
Scopes that cannot be focused are called focus fences. Focus fences keep the focus chain navigation inside the scope and do not allow the focus chain navigation to enter nor to leave the scope.
Focus fences are useful when you do not want the focus chain navigation to leave the scope boundaries. For example, use focus fences in overlays, where the focus navigation must be kept within the overlay content.
This example shows the focus fence behavior:
Specifies the reason the node is focused.
Enumerator | |
---|---|
UnknownReason |
The focus reason is unknown. |
FocusChainNavigationReason |
The focus is moved as a result of navigation in the focus chain. |
DisabledFocusReason |
The EnabledProperty or VisibleProperty of the node with the active focus was set to false. The value is only used in post-focus messages. |
EnabledFocusReason |
The EnabledProperty or VisibleProperty of the node with the logical focus was set to true. The value is only used in post-focus messages. |
OtherFocusReason |
The focus is moved due to some other reason than Tab or backtab keys or tap or mouse button press. |
Specifies the direction of the focus move.
Enumerator | |
---|---|
PreviousFocusable |
The focus is moved to the previous focusable node. |
NextFocusable |
The focus is moved to the next focusable node. |
UpFocusable |
The focus is moved to the node set in UpNavigationNodePathProperty property. |
DownFocusable |
The focus is moved to the node set in DownNavigationNodePathProperty property. |
LeftFocusable |
The focus is moved to the node set in LeftNavigationNodePathProperty property. |
RightFocusable |
The focus is moved to the node set in RightNavigationNodePathProperty property. |
|
static |
Returns the value of the NextFocusNodePathProperty property for the node on which you call this function.
node | A node that has the NextFocusNodePathProperty property attached. |
|
static |
Sets the value of the NextFocusNodePathProperty property.
node | A node which has the NextFocusNodePathProperty property attached and for which you want to set the value. |
next | The value of the NextFocusNodePathProperty property you want to set. The value must be a relative path to the destination node. |
|
static |
Returns the value of the PreviousFocusNodePathProperty property for the node on which you call this function.
node | A node that has the PreviousFocusNodePathProperty property attached. |
|
static |
Sets the value of the PreviousFocusNodePathProperty property.
node | A node which has the PreviousFocusNodePathProperty property attached and for which you want to set the value. |
previous | The value of the PreviousFocusNodePathProperty property you want to set. The value must be a relative path to the destination node. |
|
static |
Returns the value of the UpNavigationNodePathProperty on the node on which you call this function.
node | A node that has the UpNavigationNodePathProperty property attached. |
|
static |
Sets the value of the UpNavigationNodePathProperty property.
node | A node which has the UpNavigationNodePathProperty property attached and for which you want to set the value. |
path | The value of the UpNavigationNodePathProperty property you want to set. The value must be a relative path to the destination node. |
|
static |
Returns the value of the DownNavigationNodePathProperty on the node on which you call this function.
node | A node that has the DownNavigationNodePathProperty property attached. |
|
static |
Sets the value of the DownNavigationNodePathProperty property.
node | A node which has the DownNavigationNodePathProperty property attached and for which you want to set the value. |
path | The value of the DownNavigationNodePathProperty property you want to set. The value must be a relative path to the destination node. |
|
static |
Returns the value of the LeftNavigationNodePathProperty on the node on which you call this function.
node | A node that has the LeftNavigationNodePathProperty property attached. |
|
static |
Sets the value of the LeftNavigationNodePathProperty property.
node | A node which has the LeftNavigationNodePathProperty property attached and for which you want to set the value. |
path | The value of the LeftNavigationNodePathProperty property you want to set. The value must be a relative path to the destination node. |
|
static |
Returns the value of the RightNavigationNodePathProperty on the node on which you call this function.
node | A node that has the RightNavigationNodePathProperty property attached. |
|
static |
Sets the value of the RightNavigationNodePathProperty property.
node | A node which has the RightNavigationNodePathProperty property attached and for which you want to set the value. |
path | The value of the RightNavigationNodePathProperty property you want to set. The value must be a relative path to the destination node. |
|
static |
Returns the value of the FocusScopeProperty property for the node on which you call this function.
node | A node that has the FocusScopeProperty property attached. |
|
static |
Sets the value of the FocusScopeProperty property for the node.
node | A node which gets the FocusScopeProperty property attached and for which you want to set the value. |
isScope | The value of the FocusScopeProperty property you want to set. |
|
static |
Returns true if the node is a focus fence.
node | The node to check for focus fence. |
|
static |
Creates the property editor info for the FocusManager.
NodeSharedPtr kanzi::FocusManager::trySetActiveFocus | ( | NodeSharedPtr | newFocusNode, |
FocusReason | reason | ||
) |
Tries to set the active focus to the newFocusNode and specifies the reason for moving the focus.
The action fails if the node is not yet attached, or if the FocusableProperty of the node, or one of its ancestors, is not set to true. The action fails also if there is no focusable node found in the focus chain and the reason is FocusChainNavigationReason. The method takes the next focus candidate from the focus chain in forward direction.
newFocusNode | The node which receives the active focus. If you pass an empty shared pointer, the method returns the active focus node. |
reason | The reason the focus is moved. Use UnknownReason if the reason is unknown. |
NodeSharedPtr kanzi::FocusManager::trySetActiveFocus | ( | NodeSharedPtr | newFocusNode | ) |
An overload of trySetActiveFocus() using UnknownReason to move the active focus.
newFocusNode | The node which receives the active focus. Use an empty shared pointer to remove the active focus. remove the active focus. |
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocus | ( | FocusChainDirection | direction | ) |
Tries to set the active focus to a node relative to the current active focus node using the focus chain navigation.
The method takes the next focus candidate from the focus chain in the given direction.
The action fails if:
direction | The direction to query the next focusable node. |
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocusForward | ( | ) |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in forward direction.
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocusBackward | ( | ) |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in backward direction.
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocusUpward | ( | ) |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in upward direction.
The move is possible only when the UpNavigationNodePathProperty points to a valid node.
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocusDownward | ( | ) |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in downward direction.
The move is possible only when the DownNavigationNodePathProperty points to a valid node.
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocusLeft | ( | ) |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in left direction.
The move is possible only when the LeftNavigationNodePathProperty points to a valid node.
NodeSharedPtr kanzi::FocusManager::tryMoveActiveFocusRight | ( | ) |
The method is a specialization of tryMoveActiveFocus(FocusChainDirection) moving active focus from the current active focus node in right direction.
The move is possible only when the RightNavigationNodePathProperty points to a valid node.
NodeSharedPtr kanzi::FocusManager::getActiveFocus | ( | ) | const |
Returns the node that has active focus.
If the function returns an empty shared pointer, the active focus is not set.
|
friend |
|
friend |
|
friend |
|
static |
|
static |
The property overrides the default focus chain navigation order for the PreviousFocusable direction.
The value must be a relative path to the destination node. To reset the override, set the value of the property to an empty string.
|
static |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the UpFocusable direction in the tryMoveActiveFocus.
The value must be a relative path to the destination node.
|
static |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the DownFocusable direction in the tryMoveActiveFocus.
The value must be a relative path to the destination node.
|
static |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the LeftFocusable direction in the tryMoveActiveFocus.
The value must be a relative path to the destination node.
|
static |
The property holds the path to the node to navigate from the node to which the property is attached, when you specify the RightFocusable direction in the tryMoveActiveFocus.
The value must be a relative path to the destination node.
|
static |
Specifies that the node to which the property is attached is a focus scope.
|
static |
The message dispatched to the active focus node and its ascendants before losing focus.
This is the first message that Kanzi dispatches when you move the focus from the active focus node to the next focusable node during the trySetActiveFocus() call. The message handler can reject the focus move by calling PreFocusMessageArguments::setAccepted(false).
|
static |
The message dispatched to the next focusable node.
Message handlers can reject focus move by calling PreFocusMessageArguments::setAccepted(false). To avoid unnecessary propagation of the message through the scene graph, it is good practice to set the message as handled at this time.
|
static |
Informs the old active focus node about losing the active focus.
The message handlers can use this message to perform the required tasks after a node loses the focus.
|
static |
Informs the new active focus node about getting the active focus.
The message handlers can use this message to perform the required tasks after a node gets the focus.